package com.yzd.learnjava.concurrency;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import com.yzd.learnjava.util.Print;

public class WaxOMatic {
	public static void main(String[] args) throws InterruptedException {
		Car car = new Car();
		ExecutorService exec = Executors.newCachedThreadPool();
		exec.execute(new WaxOff(car));
		exec.execute(new WaxOn(car));
		TimeUnit.SECONDS.sleep(5);
		exec.shutdown();
	}
}

class Car{
	private boolean waxOn = false ;
	public synchronized void waxed() {
		waxOn = true;
		notifyAll();
	}
	
	public synchronized void buffed() {
		waxOn = false ;
		notifyAll();
	}
	
	public synchronized void waitForBuffing() throws InterruptedException {
		if(waxOn == true) {
			wait();
		}
	}
	
	public synchronized void waitForWaxing() throws InterruptedException {
		if(waxOn == false) {
			wait();
		}
	}
}

class WaxOn implements Runnable{
	private Car car ;
	public WaxOn(Car c) {
		car = c ;
	}
	
	public void run() {
		try {
			while(!Thread.interrupted()) {
				Print.print("Wax on");
				TimeUnit.MILLISECONDS.sleep(200);
				car.waxed();
				car.waitForBuffing();
			}
		} catch (InterruptedException e) {
			Print.print("Exiting via Interrupted");
		}
		
		Print.print("Ending Wax On Task");
	}
}

class WaxOff implements Runnable{
	private Car car ;
	public WaxOff(Car c ) {
		car = c;
	}
	public void run() {
		try {
			while(!Thread.interrupted()) {
				car.waitForWaxing();
				Print.print("Wax Off");
				TimeUnit.MILLISECONDS.sleep(200);
				car.buffed();
			}
		} catch (InterruptedException e) {
			Print.print("Exiting via Interrupted");
		}
		Print.print("Ending Wax Off Task");
	}
}




























